<template>
  <div class="service-container">
    <div class="service-header">
      <h2>在线客服管理</h2>
      <div class="service-status">
        <span>当前在线客服：{{ onlineServiceCount }}/{{ totalServiceCount }}</span>
        <el-switch
          v-model="onlineStatus"
          active-text="在线"
          inactive-text="离线"
          @change="toggleOnlineStatus"
        ></el-switch>
      </div>
    </div>
    
    <el-row :gutter="20">
      <el-col :span="6">
        <div class="session-list-container">
          <div class="session-list-header">
            <span>会话列表</span>
            <el-select v-model="sessionFilter" placeholder="全部会话" size="small">
              <el-option label="全部会话" value="all"></el-option>
              <el-option label="进行中" value="active"></el-option>
              <el-option label="已关闭" value="closed"></el-option>
            </el-select>
          </div>
          <div class="session-list">
            <div
              v-for="session in filteredSessions"
              :key="session.id"
              :class="['session-item', { active: currentSession && currentSession.id === session.id }]"
              @click="selectSession(session)"
            >
              <el-avatar :size="40" :src="session.userAvatar || defaultAvatar"></el-avatar>
              <div class="session-info">
                <div class="session-name">{{ session.userName || '访客' + session.userId }}</div>
                <div class="session-message">{{ session.lastMessage || '暂无消息' }}</div>
              </div>
              <div class="session-meta">
                <div class="session-time">{{ formatTime(session.updateTime) }}</div>
                <el-badge v-if="session.unreadCount > 0" :value="session.unreadCount" class="session-badge"></el-badge>
              </div>
            </div>
          </div>
        </div>
      </el-col>
      
      <el-col :span="18">
        <div class="chat-container" v-if="currentSession">
          <div class="chat-header">
            <div class="user-info">
              <span class="user-name">{{ currentSession.userName || '访客' + currentSession.userId }}</span>
              <span class="session-id">会话ID: {{ currentSession.id }}</span>
            </div>
            <div class="header-actions">
              <el-button size="small" type="danger" @click="closeSession" :disabled="currentSession.status === 0">结束会话</el-button>
            </div>
          </div>
          
          <div class="chat-messages" ref="messageBox">
            <div v-for="(message, index) in messages" :key="index" :class="['message', message.senderType === 2 ? 'service' : 'user']">
              <template v-if="message.senderType === 1">
                <el-avatar :size="36" :src="currentSession.userAvatar || defaultAvatar"></el-avatar>
                <div class="message-content">
                  <div class="message-text">{{ message.content }}</div>
                  <div class="message-time">{{ formatTime(message.createTime) }}</div>
                </div>
              </template>
              <template v-else>
                <div class="message-content">
                  <div class="message-text">{{ message.content }}</div>
                  <div class="message-time">{{ formatTime(message.createTime) }}</div>
                </div>
                <el-avatar :size="36" :src="serviceAvatar"></el-avatar>
              </template>
            </div>
          </div>
          
          <div class="chat-input">
            <el-input
              type="textarea"
              :rows="3"
              placeholder="请输入回复内容..."
              v-model="inputMessage"
              @keyup.enter.native="sendMessage"
              :disabled="currentSession.status === 0"
            ></el-input>
            <div class="input-actions">
              <el-button type="primary" @click="sendMessage" :disabled="!inputMessage.trim() || currentSession.status === 0">发送</el-button>
            </div>
          </div>
        </div>
        
        <div class="no-session" v-else>
          <el-empty description="请选择一个会话"></el-empty>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { formatDate } from '@/utils/date';

export default {
  name: 'ServiceManagement',
  data() {
    return {
      onlineStatus: true,
      onlineServiceCount: 1,
      totalServiceCount: 3,
      sessionFilter: 'all',
      sessions: [],
      currentSession: null,
      messages: [],
      inputMessage: '',
      websocket: null,
      serviceId: 1, // 当前客服ID
      serviceName: '客服小王',
      serviceAvatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
      defaultAvatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
      heartbeatTimer: null,
      reconnectTimer: null,
      reconnectAttempts: 0,
      maxReconnectAttempts: 5
    };
  },
  computed: {
    filteredSessions() {
      if (this.sessionFilter === 'all') {
        return this.sessions;
      }
      return this.sessions.filter(session => {
        return this.sessionFilter === 'active' ? session.status === 1 : session.status === 0;
      });
    }
  },
  created() {
    // 模拟数据
    this.sessions = [
      {
        id: '1001',
        userId: 10001,
        userName: '张三',
        userAvatar: null,
        serviceId: 1,
        status: 1,
        lastMessage: '您好，我想咨询一下租车价格',
        unreadCount: 2,
        createTime: new Date(Date.now() - 3600000),
        updateTime: new Date(Date.now() - 60000)
      },
      {
        id: '1002',
        userId: 10002,
        userName: '李四',
        userAvatar: null,
        serviceId: 1,
        status: 1,
        lastMessage: '请问押金什么时候退还？',
        unreadCount: 0,
        createTime: new Date(Date.now() - 7200000),
        updateTime: new Date(Date.now() - 3600000)
      },
      {
        id: '1003',
        userId: 10003,
        userName: '王五',
        userAvatar: null,
        serviceId: 1,
        status: 0,
        lastMessage: '谢谢，再见',
        unreadCount: 0,
        createTime: new Date(Date.now() - 86400000),
        updateTime: new Date(Date.now() - 43200000)
      }
    ];
  },
  mounted() {
    // 连接WebSocket
    this.connectWebSocket();
    
    // 获取会话列表
    this.getServiceSessions();
  },
  beforeDestroy() {
    // 关闭WebSocket连接
    this.closeWebSocket();
  },
  methods: {
    formatTime(time) {
      if (!time) return '';
      return formatDate(new Date(time), 'HH:mm');
    },
    
    selectSession(session) {
      this.currentSession = session;
      this.messages = []; // 清空消息
      
      // 获取会话消息
      this.getSessionMessages(session.id);
      
      // 标记消息为已读
      if (session.unreadCount > 0) {
        this.markMessagesAsRead(session.id);
        session.unreadCount = 0;
      }
    },
    
    closeSession() {
      if (!this.currentSession) return;
      
      this.$confirm('确定要结束此会话吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 调用关闭会话API
        // 实际项目中应调用后端API
        this.currentSession.status = 0;
        this.$message.success('会话已结束');
      }).catch(() => {});
    },
    
    sendMessage() {
      if (!this.inputMessage.trim() || !this.currentSession) return;
      
      // 创建消息对象
      const message = {
        type: 'CHAT',
        sessionId: this.currentSession.id,
        senderId: this.serviceId,
        senderType: 2,
        receiverId: this.currentSession.userId,
        content: this.inputMessage,
        timestamp: Date.now()
      };
      
      // 发送消息
      if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
        this.websocket.send(JSON.stringify(message));
      }
      
      // 添加到消息列表
      this.messages.push({
        id: Date.now(),
        sessionId: this.currentSession.id,
        senderId: this.serviceId,
        senderType: 2,
        receiverId: this.currentSession.userId,
        content: this.inputMessage,
        messageType: 1,
        readStatus: 0,
        createTime: new Date()
      });
      
      // 更新会话最后一条消息
      this.currentSession.lastMessage = this.inputMessage;
      this.currentSession.updateTime = new Date();
      
      // 清空输入框
      this.inputMessage = '';
      
      // 滚动到底部
      this.scrollToBottom();
    },
    
    scrollToBottom() {
      this.$nextTick(() => {
        const messageBox = this.$refs.messageBox;
        if (messageBox) {
          messageBox.scrollTop = messageBox.scrollHeight;
        }
      });
    },
    
    toggleOnlineStatus(status) {
      // 调用更新客服状态API
      // 实际项目中应调用后端API
      this.$message.success(status ? '您已上线' : '您已离线');
      
      if (status) {
        // 上线时连接WebSocket
        this.connectWebSocket();
      } else {
        // 下线时关闭WebSocket
        this.closeWebSocket();
      }
    },
    
    // API调用方法
    getServiceSessions() {
      // 调用获取客服会话列表API
      // 实际项目中应调用后端API
      // 这里使用模拟数据
    },
    
    getSessionMessages(sessionId) {
      // 调用获取会话消息API
      // 实际项目中应调用后端API
      // 这里使用模拟数据
      this.messages = [
        {
          id: 1,
          sessionId: sessionId,
          senderId: this.currentSession.userId,
          senderType: 1,
          receiverId: this.serviceId,
          content: '您好，我想咨询一下租车价格',
          messageType: 1,
          readStatus: 1,
          createTime: new Date(Date.now() - 3600000)
        },
        {
          id: 2,
          sessionId: sessionId,
          senderId: this.serviceId,
          senderType: 2,
          receiverId: this.currentSession.userId,
          content: '您好，我们的租车价格根据车型不同而有所差异，经济型轿车一般每天200-300元，SUV每天300-500元，豪华车型每天500元起。具体价格请在车辆详情页查看。',
          messageType: 1,
          readStatus: 1,
          createTime: new Date(Date.now() - 3500000)
        },
        {
          id: 3,
          sessionId: sessionId,
          senderId: this.currentSession.userId,
          senderType: 1,
          receiverId: this.serviceId,
          content: '请问押金是多少？',
          messageType: 1,
          readStatus: 1,
          createTime: new Date(Date.now() - 3400000)
        },
        {
          id: 4,
          sessionId: sessionId,
          senderId: this.serviceId,
          senderType: 2,
          receiverId: this.currentSession.userId,
          content: '我们的押金政策是：经济型轿车2000元，中高级轿车3000-5000元，豪华车型10000元起。押金在还车时会全额退还（如无违章和车辆损伤）。',
          messageType: 1,
          readStatus: 1,
          createTime: new Date(Date.now() - 3300000)
        }
      ];
      
      // 滚动到底部
      this.scrollToBottom();
    },
    
    markMessagesAsRead(sessionId) {
      // 调用标记消息已读API
      // 实际项目中应调用后端API
    },
    
    // WebSocket相关方法
    connectWebSocket() {
      // 检查浏览器是否支持WebSocket
      if ('WebSocket' in window) {
        // 创建WebSocket连接
        const wsUrl = `ws://${window.location.hostname}:8086/service/ws/chat/${this.serviceId}/2`;
        this.websocket = new WebSocket(wsUrl);
        
        // 连接成功
        this.websocket.onopen = () => {
          console.log('WebSocket连接成功');
          this.reconnectAttempts = 0;
          
          // 发送心跳包
          this.startHeartbeat();
          
          // 发送连接消息
          const connectMessage = {
            type: 'CONNECT',
            senderId: this.serviceId,
            senderType: 2,
            timestamp: Date.now()
          };
          this.websocket.send(JSON.stringify(connectMessage));
        };
        
        // 接收消息
        this.websocket.onmessage = (event) => {
          const message = JSON.parse(event.data);
          console.log('收到消息:', message);
          
          // 处理不同类型的消息
          switch (message.type) {
            case 'CONNECT':
              // 连接成功，不做处理
              break;
            case 'CHAT':
              // 接收聊天消息
              if (message.senderType === 1) { // 用户消息
                // 查找对应的会话
                const session = this.sessions.find(s => s.id === message.sessionId);
                if (session) {
                  // 更新会话最后一条消息
                  session.lastMessage = message.content;
                  session.updateTime = new Date();
                  
                  // 如果不是当前会话，增加未读消息数
                  if (!this.currentSession || this.currentSession.id !== session.id) {
                    session.unreadCount++;
                  } else {
                    // 如果是当前会话，添加到消息列表
                    this.messages.push({
                      id: Date.now(),
                      sessionId: message.sessionId,
                      senderId: message.senderId,
                      senderType: message.senderType,
                      receiverId: message.receiverId,
                      content: message.content,
                      messageType: 1,
                      readStatus: 0,
                      createTime: new Date()
                    });
                    
                    // 滚动到底部
                    this.scrollToBottom();
                    
                    // 标记为已读
                    this.markMessagesAsRead(session.id);
                  }
                } else {
                  // 创建新会话
                  const newSession = {
                    id: message.sessionId,
                    userId: message.senderId,
                    userName: '访客' + message.senderId,
                    userAvatar: null,
                    serviceId: this.serviceId,
                    status: 1,
                    lastMessage: message.content,
                    unreadCount: 1,
                    createTime: new Date(),
                    updateTime: new Date()
                  };
                  this.sessions.unshift(newSession);
                }
              }
              break;
            case 'HEARTBEAT':
              // 心跳响应，不做处理
              break;
            default:
              break;
          }
        };
        
        // 连接关闭
        this.websocket.onclose = () => {
          console.log('WebSocket连接关闭');
          this.stopHeartbeat();
          
          // 尝试重连
          if (this.onlineStatus && this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectTimer = setTimeout(() => {
              this.reconnectAttempts++;
              console.log(`尝试第${this.reconnectAttempts}次重连`);
              this.connectWebSocket();
            }, 3000);
          }
        };
        
        // 连接错误
        this.websocket.onerror = (error) => {
          console.error('WebSocket连接错误:', error);
        };
      } else {
        console.error('浏览器不支持WebSocket');
      }
    },
    
    closeWebSocket() {
      if (this.websocket) {
        // 发送关闭消息
        const closeMessage = {
          type: 'CLOSE',
          senderId: this.serviceId,
          senderType: 2,
          timestamp: Date.now()
        };
        
        try {
          this.websocket.send(JSON.stringify(closeMessage));
        } catch (e) {
          console.error('发送关闭消息失败:', e);
        }
        
        // 关闭连接
        this.websocket.close();
        this.websocket = null;
        
        // 停止心跳
        this.stopHeartbeat();
        
        // 清除重连定时器
        if (this.reconnectTimer) {
          clearTimeout(this.reconnectTimer);
          this.reconnectTimer = null;
        }
      }
    },
    
    startHeartbeat() {
      this.heartbeatTimer = setInterval(() => {
        if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
          const heartbeatMessage = {
            type: 'HEARTBEAT',
            timestamp: Date.now()
          };
          this.websocket.send(JSON.stringify(heartbeatMessage));
        }
      }, 30000); // 30秒发送一次心跳
    },
    
    stopHeartbeat() {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.service-container {
  padding: 20px;
  
  .service-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    
    h2 {
      margin: 0;
    }
    
    .service-status {
      display: flex;
      align-items: center;
      
      span {
        margin-right: 15px;
      }
    }
  }
  
  .session-list-container {
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    height: 600px;
    display: flex;
    flex-direction: column;
    
    .session-list-header {
      padding: 15px;
      border-bottom: 1px solid #ebeef5;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    
    .session-list {
      flex: 1;
      overflow-y: auto;
      
      .session-item {
        padding: 15px;
        display: flex;
        cursor: pointer;
        border-bottom: 1px solid #f0f0f0;
        
        &:hover {
          background-color: #f5f7fa;
        }
        
        &.active {
          background-color: #ecf5ff;
        }
        
        .session-info {
          flex: 1;
          margin-left: 10px;
          overflow: hidden;
          
          .session-name {
            font-weight: 500;
            margin-bottom: 5px;
          }
          
          .session-message {
            color: #909399;
            font-size: 13px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
        }
        
        .session-meta {
          text-align: right;
          
          .session-time {
            font-size: 12px;
            color: #909399;
            margin-bottom: 5px;
          }
        }
      }
    }
  }
  
  .chat-container {
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    height: 600px;
    display: flex;
    flex-direction: column;
    
    .chat-header {
      padding: 15px;
      border-bottom: 1px solid #ebeef5;
      display: flex;
      justify-content: space-between;
      align-items: center;
      
      .user-info {
        .user-name {
          font-weight: 500;
          margin-right: 10px;
        }
        
        .session-id {
          font-size: 12px;
          color: #909399;
        }
      }
    }
    
    .chat-messages {
      flex: 1;
      padding: 15px;
      overflow-y: auto;
      background-color: #f5f7fa;
      
      .message {
        display: flex;
        margin-bottom: 15px;
        
        &.user {
          align-items: flex-start;
          
          .el-avatar {
            margin-right: 10px;
          }
          
          .message-content {
            .message-text {
              background-color: #fff;
              color: #606266;
              border-radius: 0 8px 8px 8px;
            }
          }
        }
        
        &.service {
          justify-content: flex-end;
          align-items: flex-start;
          
          .el-avatar {
            margin-left: 10px;
          }
          
          .message-content {
            align-items: flex-end;
            
            .message-text {
              background-color: #409eff;
              color: #fff;
              border-radius: 8px 0 8px 8px;
            }
            
            .message-time {
              text-align: right;
            }
          }
        }
        
        .message-content {
          max-width: 70%;
          display: flex;
          flex-direction: column;
          
          .message-text {
            padding: 10px 15px;
            word-break: break-word;
            line-height: 1.5;
          }
          
          .message-time {
            font-size: 12px;
            color: #909399;
            margin-top: 5px;
          }
        }
      }
    }
    
    .chat-input {
      padding: 15px;
      border-top: 1px solid #ebeef5;
      
      .input-actions {
        display: flex;
        justify-content: flex-end;
        margin-top: 10px;
      }
    }
  }
  
  .no-session {
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    height: 600px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style> 